#include <iostream>
#include <memory>
#include <vector>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "HttpServer.hpp"
#include "Util.hpp"

#define ROOT "./wwwroot"
#define HOMEPAGE "index.html"

void Usage(std::string proc)
{
    std::cout << "\nUsage: " << proc << " port\n" << std::endl;
}

void HttplerHttpRequest(int sock)
{
    // 1.读取请求
    char buffer[10240];
    ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (s > 0)
    {
        buffer[s] = 0;
    }

    std::cout << buffer << "\n--------------------------------\n" << std::endl;


    // 这里处理报头  一般是 GET /访问的路径  HTTP/1.1   -> 最后面是HTTP的版本
    // 我们要做的就是把访问的路径提取出来,如果用户不指定路径, 默认就是 -> / -> 根路径
    std::vector<std::string> vline;
    Util::cutString(buffer, "\n", &vline);
    // 读取到的是整个HTTP报文, 第一行 -> 请求行  第二行往后 -> 请求报头 -> key value -> 用户的基本信息  空行  有效载荷

    std::vector<std::string> vblock;
    Util::cutString(vline[0], " ", &vblock);  // 提取第1行中的路径 vblock[1]就是路径

    std::string path = vblock[1];

    // 这里的file是一个请求路径，但是在get方法请求的时候会携带参数，格式是path?param=value&param=value
    // /a/b/haha.html?user=lisi&pwd=123456这样的
    auto it = path.find('?');
    std::string file;
    if (it == std::string::npos) {
        // 没有找到，那就证明没有参数，path就是file
        file = path;
    }
    else
    {
        file = path.substr(0, it);
    }

    std::string target = ROOT;

    if (file == "/")
        file = "/index.html";
    target += file;
    std::cout << "target: " << target << std::endl;

    std::string content;
    std::ifstream in(target);
    if (in.is_open())
    {
        std::string line;
        while (std::getline(in, line))
        {
            content += line;
        }
        in.close();
    }

    // // 2.构建Http响应
    // // 1.0 版本  简单的网页
    // std::string HttpResponse = "HTTP/1.1 200 OK\r\n";  // 状态行
    // HttpResponse += "\r\n"; // 空行
    // HttpResponse += "<html><h3>hello Http!</h3></html>"; // 内容 -> 一个简单的网页
    // send(sock, HttpResponse.c_str(), HttpResponse.size(), 0);

    
    // 2.0版本
    std::string HttpResponse;
    // 这里的判断条件，是有没有响应体作为成功与否的条件的，但是对于get方法来说，他的数据是携带在请求行中的，
    // http://106.54.42.34:8080/a/b/haha.html?user=lisi&pwd=123456
    // 你的文件名称应该不是haha.html,是这个haha.html?user=lisi&pwd=123456，你没有对get的这种参数做解析，而是直接放到了path中，所以解析失败了
    if (content.empty())
    {
        HttpResponse = "HTTP/1.1 302 Found\r\n";     // 404 没有找到该网页
        HttpResponse +=  "Location: http://106.54.42.34:8080/a/b/404.html\r\n";  // 没有找到我们就给他重定向到其他网页
    }
    else
    {
        HttpResponse = "HTTP/1.1 200 OK\r\n"; // 状态行
        HttpResponse += ("Content-Type: text/html\r\n"); // 
        HttpResponse += ("content-Length:" + std::to_string(content.size()) + "\r\n");
        HttpResponse += ("Set-Cookie: 这里一个cookie\r\n");
    }

    HttpResponse += "\r\n"; // 空行
    HttpResponse += content; // 正文
    send(sock, HttpResponse.c_str(), HttpResponse.size(), 0);
}


int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(0);
    }

    std::unique_ptr<HttpServer> src(new HttpServer(atoi(argv[1]), HttplerHttpRequest));
    src->start();
    return 0;
}